package com.floreantpos.ui.dialog;

import com.floreantpos.config.PrintConfig;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JSeparator;

import net.miginfocom.swing.MigLayout;

import com.floreantpos.main.Application;
import com.floreantpos.model.Restaurant;
import com.floreantpos.model.Ticket;
import com.floreantpos.model.TicketItem;
import com.floreantpos.model.TicketItemModifier;
import com.floreantpos.model.TicketItemModifierGroup;
import com.floreantpos.model.dao.RestaurantDAO;
import com.floreantpos.model.dao.TicketDAO;
import com.floreantpos.print.PosPrintService;
import com.floreantpos.swing.PosButton;
import com.googlecode.floreo.ecf.bematech.BematechMP2100;

public class TransactionCompletionDialog extends POSDialog {

  private List<Ticket> tickets;
  private double tenderedAmount;
  private double totalAmount;
  private double paidAmount;
  private double dueAmount;
  private double dueAmountBeforePaid;
  private double gratuityAmount;
  
  private Boolean paymentTicket;

  private JLabel lblTenderedAmount;
  private JLabel lblTotalAmount;
  private JLabel lblPaidAmount;
  private JLabel lblDueAmount;
  private JLabel lblChangeDue;
  private JLabel lblGratuityAmount;
  
  private PosButton btnPrintClose = new PosButton(com.floreantpos.POSConstants.PRINT_AND_CLOSE);
  private PosButton btnClose = new PosButton("Fechar");  
  
  private TransactionCompletionDialog(Frame parent) {
    super(parent, true);

    setTitle(com.floreantpos.POSConstants.TRANSACTION_COMPLETED);

    setLayout(new MigLayout("align 50% 0%, ins 20", "[]20[]", ""));

    add(createLabel(com.floreantpos.POSConstants.TOTAL_VALUE_ORDER, JLabel.LEFT), "grow");
    lblTotalAmount = createLabel("0,00", JLabel.RIGHT);
    add(lblTotalAmount, "grow");

    add(createLabel(com.floreantpos.POSConstants.AMOUNT_RECEIVED, JLabel.LEFT), "newline,grow");
    lblTenderedAmount = createLabel("0,00", JLabel.RIGHT);
    add(lblTenderedAmount, "grow");

    add(new JSeparator(), "newline,span, grow");

    add(createLabel(com.floreantpos.POSConstants.AMOUNT_PAID_ORDER, JLabel.LEFT), "newline,grow");
    lblPaidAmount = createLabel("0,00", JLabel.RIGHT);
    add(lblPaidAmount, "grow");

    add(createLabel(com.floreantpos.POSConstants.AMOUNT_OPEN, JLabel.LEFT), "newline,grow");
    lblDueAmount = createLabel("0,00", JLabel.RIGHT);
    add(lblDueAmount, "grow");

    add(new JSeparator(), "newline,span, grow");

    add(createLabel(com.floreantpos.POSConstants.VALUE_BONUS, JLabel.LEFT), "newline,grow");
    lblGratuityAmount = createLabel("0,00", JLabel.RIGHT);
    add(lblGratuityAmount, "grow");

    add(new JSeparator(), "newline,span, grow");

    add(createLabel(com.floreantpos.POSConstants.VALUE_CHANGE, JLabel.LEFT), "grow");
    lblChangeDue = createLabel("0,00", JLabel.RIGHT);
    add(lblChangeDue, "grow");

    add(new JSeparator(), "sg mygroup,newline,span,grow");
    btnClose.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        dispose();
      }

    });
  
    btnPrintClose.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          for (Ticket ticket : tickets) {
            if (Application.isTestSystem() || isPaymentTicket()) {
              PosPrintService.printTicket(ticket);
            } else {
              
              Restaurant restaurant = RestaurantDAO.getInstance().get(Integer.valueOf(1));
              
              String msgEcf = restaurant.getMsgEcf();
              if (msgEcf == null) {
                msgEcf = "";
              }
              
              Integer cupomFiscalErrors = 0;
              
              if (!BematechMP2100.abreCupom(ticket.getTaxId())) {
                cupomFiscalErrors++;
              }
              
              List<TicketItem> ticketItems = ticket.getTicketItems();
              
              if (ticketItems != null) {
                for (TicketItem ticketItem : ticketItems) {
                  String itemName = ticketItem.getName();
                  List<TicketItemModifierGroup> checkPizzaModifierGroups = ticketItem.getTicketItemModifierGroups();
                  if (checkPizzaModifierGroups != null) {
                    for (TicketItemModifierGroup modifierGroup : checkPizzaModifierGroups) {
                      List<TicketItemModifier> modifiers = modifierGroup.getTicketItemModifiers();
                      if (modifiers != null) {
                        for (TicketItemModifier modifier : modifiers) {
                          if (modifier.isPizzaModifier()) {
                            if (modifier.getName().length() > 3) {
                              itemName = itemName + " " + modifier.getName().substring(0, 3);
                            } else {
                              itemName = itemName + " " + modifier.getName();
                            }                           
                          }
                        }
                      }
                    }
                  }
                  
                  if (itemName.length() > 28) {
                    itemName = itemName.substring(0, 28);
                  }
                  
                  if (!BematechMP2100.vendeItem(String.valueOf(ticketItem.getItemId()), itemName, ticketItem.getEcfTaxRateAsString(), "I", ticketItem.getItemCountAsString(), 2, ticketItem.getUnitPriceAsString(), "$", "00000000")) {
                    cupomFiscalErrors++;
                  } 
                  
                  List<TicketItemModifierGroup> modifierGroups = ticketItem.getTicketItemModifierGroups();
                  if (modifierGroups != null) {
                    for (TicketItemModifierGroup modifierGroup : modifierGroups) {
                      List<TicketItemModifier> modifiers = modifierGroup.getTicketItemModifiers();
                      if (modifiers != null) {
                        for (TicketItemModifier modifier : modifiers) {
                          if (modifier.getTotalAmount() != 0 && !modifier.isPizzaModifier()) {
                            String modifierName = "+" + modifier.getName();
                            if (!BematechMP2100.vendeItem(String.valueOf(modifier.getModifierId()), modifierName, ticketItem.getEcfTaxRateAsString(), "I", modifier.getItemCountAsString(), 2, modifier.getUnitPriceAsString(), "$", "00000000")) {
                              cupomFiscalErrors++;
                            } 
                          }
                        }
                      }
                    }
                  }
                }
              }
              String cupomFiscal = "";
              if (ticket.getDiscountAmount() > 0) {
                String valorAcresDesc = Application.formatNumber(ticket.getDiscountAmount()).replace(".", "").replace(",", "");
                String valorPago = Application.formatNumber(ticket.getSubtotalAmount() - ticket.getDiscountAmount()).replace(".", "").replace(",", "");
                if (BematechMP2100.fechaCupom(ticket.getPaymentMethod(), "D", "$", valorAcresDesc, valorPago, msgEcf)) {
                  cupomFiscal = BematechMP2100.numeroCupom().trim();
                } else {
                  cupomFiscalErrors++;
                }
              } else {
                if (BematechMP2100.fechaCupomResumido(ticket.getPaymentMethod(), msgEcf)) {
                  cupomFiscal = BematechMP2100.numeroCupom().trim();
                } else {
                  cupomFiscalErrors++;
                }
              }
              if (cupomFiscalErrors > 0) {
                String mensagemErroCupomFiscal = "Erro na emissão do Cupom Fiscal.\n\n"
                        + "Se necessário, cancele o Cupom Fiscal Atual.\n"
                        + "Em seguida, identifique o problema, reabra o pedido e emita novamente o Cupom Fiscal.\n\n"
                        + "Obs.: Verifique a impressora e o cadastro dos itens e suas alíquotas.\n\n";                
                POSMessageDialog.showError(mensagemErroCupomFiscal);
              } else {
                TicketDAO ticketDAO = new TicketDAO();
                Ticket updateTicket = ticketDAO.get(ticket.getId());
                updateTicket.setCupomFiscal(cupomFiscal);
                ticketDAO.saveOrUpdate(updateTicket);                
              }
            }           
          }
        } catch (Exception ee) {
          POSMessageDialog.showError(Application.getPosWindow(), "Ocorreu um erro durante a impressão", ee);
        }
        dispose();
      }
    });

    add(btnPrintClose, "newline,skip, align 100%,h 50, w 120");
    add(btnClose, "skip, align 100%,h 50, w 120");

    setResizable(false);
  }

  protected JLabel createLabel(String text, int alignment) {
    JLabel label = new JLabel(text);
    label.setFont(new java.awt.Font("Tahoma", 1, 36));
    label.setForeground(new java.awt.Color(255, 102, 0));
    label.setHorizontalAlignment(alignment);
    label.setText(text);
    return label;
  }

  public double getTenderedAmount() {
    return tenderedAmount;
  }

  public void setTenderedAmount(double amountTendered) {
    this.tenderedAmount = amountTendered;
  }

  public void updateView() {
    lblTotalAmount.setText(Application.formatNumber(totalAmount));
    lblTenderedAmount.setText(Application.formatNumber(tenderedAmount));
    lblPaidAmount.setText(Application.formatNumber(paidAmount));
    lblDueAmount.setText(Application.formatNumber(dueAmount));
    lblGratuityAmount.setText(Application.formatNumber(gratuityAmount));

    double changeDueAmount = tenderedAmount - (dueAmountBeforePaid + gratuityAmount);
    if (changeDueAmount < 0) {
      changeDueAmount = 0;
    }
    lblChangeDue.setText(Application.formatNumber(changeDueAmount));
    
    if (Application.isTestSystem() || isPaymentTicket()) {  
      if (PrintConfig.isPrintReceiptEnabled()) {
        btnClose.setEnabled(true);
        btnPrintClose.setEnabled(true);
      } else {
        btnClose.setEnabled(true);
        btnPrintClose.setEnabled(false);
      }      
    } else {
      if (dueAmount > 0) {
        btnClose.setEnabled(true);
        btnPrintClose.setEnabled(false);
      } else {
        btnClose.setEnabled(false);
        btnPrintClose.setEnabled(true);        
      }
    }    
    
  }

  private static TransactionCompletionDialog instance;

  public static TransactionCompletionDialog getInstance() {
    if (instance == null) {
      instance = new TransactionCompletionDialog(Application.getPosWindow());
    }
    return instance;
  }

  public void setPaymentTicket(Boolean paymentTicket) {
    this.paymentTicket = paymentTicket;
  }
  
  public Boolean isPaymentTicket() {
    return paymentTicket;
  }
  
  public double getDueAmountBeforePaid() {
    return dueAmountBeforePaid;
  }

  public void setDueAmountBeforePaid(double dueAmountBeforePaid) {
    this.dueAmountBeforePaid = dueAmountBeforePaid;
  }

  public double getDueAmount() {
    return dueAmount;
  }

  public void setDueAmount(double dueAmount) {
    this.dueAmount = dueAmount;
  }

  public double getPaidAmount() {
    return paidAmount;
  }

  public void setPaidAmount(double paidAmount) {
    this.paidAmount = paidAmount;
  }

  public double getTotalAmount() {
    return totalAmount;
  }

  public void setTotalAmount(double totalAmount) {
    this.totalAmount = totalAmount;
  }

  public double getGratuityAmount() {
    return gratuityAmount;
  }

  public void setGratuityAmount(double gratuityAmount) {
    this.gratuityAmount = gratuityAmount;
  }

  public List<Ticket> getTickets() {
    return tickets;
  }

  public void setTickets(List<Ticket> tickets) {
    this.tickets = tickets;
  }
}
